import { httpError, Inject, Provide } from '@midwayjs/core'
import { Context } from '@midwayjs/koa'
import { InjectEntityModel } from '@midwayjs/typeorm'
import { Between, Repository } from 'typeorm'

import { DeleteDTO } from '@/dto'
import { SysConfigEntity } from '@/entity'
import { StateService } from '@/service'

import {
  CreateConfigDTO,
  FindConfigPageDTO,
  UpdateConfigDTO
} from './config.dto'

@Provide()
export class ConfigService {
  @Inject()
  ctx: Context

  @InjectEntityModel(SysConfigEntity)
  configModel: Repository<SysConfigEntity>

  async handleFindPage(dto: FindConfigPageDTO) {
    const { pageNum, pageSize, beginDate, endDate, ...rest } = dto

    const [list, total] = await this.configModel.findAndCount({
      where: {
        createTime: beginDate ? Between(beginDate, endDate) : null,
        ...rest
      },
      take: pageSize,
      skip: (pageNum - 1) * pageSize
    })

    return {
      pageNum,
      pageSize,
      total,
      list
    }
  }

  async handleGetValue(key: string) {
    return await this.configModel.findOne({ where: { configKey: key } })
  }

  async handleCreate(dto: CreateConfigDTO) {
    const stateService = await this.ctx.requestContext.getAsync(StateService)

    const jwtPayload = stateService.getJwtPayload()

    const oldConfig = await this.configModel.findOne({
      where: { configKey: dto.configKey }
    })

    if (oldConfig) {
      this.ctx.throw(new httpError.BadRequestError('参数配置已存在'))
    }

    const newConfig = new SysConfigEntity()

    Object.assign<any, any, Partial<SysConfigEntity>>(newConfig, dto, {
      createBy: jwtPayload.userName
    })

    await this.configModel.save(newConfig)
  }

  async handleUpdate(id: string, dto: UpdateConfigDTO) {
    const stateService = await this.ctx.requestContext.getAsync(StateService)

    const jwtPayload = stateService.getJwtPayload()
    const configId = Number(id)

    const config = await this.configModel.findOne({ where: { configId } })

    if (!config) {
      this.ctx.throw(new httpError.BadRequestError('参数配置不存在'))
    }

    Object.assign<any, any, Partial<SysConfigEntity>>(config, dto, {
      updateBy: jwtPayload.userName
    })

    await this.configModel.save(config)
  }

  async handleDelete(dto: DeleteDTO) {
    const { ids } = dto

    await this.configModel.delete(ids)
  }
}
